<?php


namespace App\Managers;


use App\Exceptions\AdminException;

abstract class BaseManager
{
    protected $modelName;

    /** @var \App\Models\BaseModel */
    protected $model;

    protected $data;                                //参数

    protected $error = '';                               //错误信息

    protected $info = '';                                //返回信息

    protected $rule;                                //

    //
    public function __construct()
    {

    }

    /**
     * @param string $modelName
     * @param mixed ...$args
     */
    public function getModel($modelName = '', ...$args)
    {
        if (!empty($modelName) && ($modelName !== $this->modelName)) {
            $this->modelName = $modelName;
            $this->model = null;
        }
        if (empty($this->model)) {
            if (is_string($this->modelName)) {
                $modelName = "\App\Models\\" . $this->modelName;
            }

            $this->model = new $modelName(...$args);
        }
        return $this->model;
    }

    /** 获取成功信息 */
    public function getInfo($default = '')
    {
        if (empty($this->info)) {
            $this->info = $default;
        }
        return $this->info;
    }

    /** 获取错误 */
    public function getError($default = '')
    {
        if (empty($this->error)) {
            $this->error = $default;
        }
        return $this->error;
    }

    /** 设置参数 */
    public function setData($key, $value = '')
    {
        if (is_array($key)) {
            $this->data = $key;
        } else {
            $this->data[$key] = $value;
        }
        return $this;
    }

    /**
     * 获取数据
     * @param string $name
     * @param null $default
     * @return array|mixed
     */
    public function getData($name = NULL, $default = null)
    {
//        isset($this->data[$name]) ? $this->data[$name] : $default)
        return is_null($name) ? $this->data : data_get($this->data, $name, $default);
    }

    public function _with()
    {
        $with = $this->getData("with", []);
        if (!empty($with)) {
            $this->getModel()->getQueryByModel()->with($with);
        }
    }

    public function _withCount()
    {
        $with = $this->getData("withCount", []);
        if (!empty($with)) {
            $this->getModel()->getQueryByModel()->withCount($with);
        }
    }

    public function _whereHasIn()
    {
        $whereHasIn = $this->getData("whereHasIn", []);
        if (!empty($whereHasIn)) {
            $model = $this->getModel()->getQueryByModel();
            foreach ($whereHasIn as $key => $value) {
                $model->whereHasIn($key, $value);
            }
        }
    }

    /** 获取列表 */
    public function lists($isPage = true)
    {
        $model = $this->getModel();
        if (method_exists($this, '_before_lists')) {
            $this->_before_lists();
        }
        if (method_exists($model, 'filter')) {
            $model->filter($this->data);
        }
        if (method_exists($this, '_with')) {
            $this->_with();
        }
        if (method_exists($this, '_withCount')) {
            $this->_withCount();
        }
        if (method_exists($this, '_whereHasIn')) {
            $this->_whereHasIn();
        }


        if (method_exists($model, 'apigrid') && $isPage) {
            $data = $model->apigrid($this->data);
        } else {
            $data = $model->getAll([], [], $this->data);
        }

        if (method_exists($this, '_format')) {
            $data = $this->_format($data);
        }
        if ($data !== false) {
            if (method_exists($this, '_after_lists')) {
                $after = $this->_after_lists($data);
                if (!is_null($after)) {
                    return $after;
                }
            }
        }

        return $data;
    }


    /**
     * 没有主键的保存
     * @param $update
     * @return bool
     */
    public function update()
    {
        $model = $this->getModel();
        if (method_exists($this, '_before_update')) {
            $before = $this->_before_update();
            if (!is_null($before)) {
                return $before;
            }
        }

        $pk = $model->getKeyName();
        if (isset($this->data[$pk]) && $this->data[$pk]) {

            return $this->save();           //有主键直接走save方法

        }

        foreach ($this->data as $key => $val) {
            if (is_array($val)) {         //假设有数值认为这是批量处理的条件
                $model->getQueryByModel()->whereIn($key, $val);
            } else {
                $model->setValue($key, $val);
            }
        }

        if (empty($model->getQueryByModel()->getQuery()->wheres)) {
            throw new AdminException("缺失update where 条件");
        }
        //保存

        if ($model->usesTimestamps()) {
            $model->exists = true;
            $model->updateTimestamps();
        }
        $dirty = $model->getDirty();
        $result = count($dirty) > 0 ? $model->getQueryByModel()->update($dirty) : true;

        if ($result !== false) {
            //调用保存后需要处理的方法
            if (method_exists($this, '_after_update')) {
                $after = $this->_after_update();
                if (!is_null($after)) {
                    return $after;
                }
            }
            $this->info = "修改成功";

            return true;
        } else {
            $this->error = "修改失败";

            return false;
        }
    }


    /** 保存 */
    public function save()
    {
        $model = $this->getModel();
        if (method_exists($this, '_before_save')) {
            $before = $this->_before_save();
            if (!is_null($before)) {
                return $before;
            }
        }
        $pk = $model->getKeyName();
        if (isset($this->data[$pk]) && $this->data[$pk]) {

            $model->exists = true;
        }
        if (method_exists($model, 'verification')) {
            //数据库自定义数据验证
            $result = $model->verification($this->data);
            if (!is_null($result)) {
                $this->error = $result;
                return false;
            }
        }
        //保存
        $model->setValue($this->data);
        $result = $model->save();
        if (empty($this->data[$pk])) {
            $this->data[$pk] = $model->$pk;
        }

        if ($result !== false) {
            //调用保存后需要处理的方法
            if (method_exists($this, '_after_save')) {
                $after = $this->_after_save();
                if (!is_null($after)) {
                    return $after;
                }
            }
            $this->info = "修改成功";
            return true;
        } else {
            $this->error = "修改失败";
            return false;
        }
    }

    public function delete()
    {
        if (method_exists($this, '_before_delete')) {
            $before = $this->_before_delete();
            if (!is_null($before)) {
                return $before;
            }
        }
        $model = $this->getModel();
        $pk = $model->getKeyName();
        $query = $model->getQueryByModel();
        if (!empty($this->data[$pk])) {
            $query->whereIn($pk, explode(',', $this->data[$pk]));
        }
        if(empty($query->getQuery()->wheres)){
            $this->error = '缺失 where 条件';
            return false;
        }
        $result = $query->delete();
        if ($result) {
            if (method_exists($this, '_after_delete')) {
                $after = $this->_after_delete();
                if (!is_null($after)) {
                    return $after;
                }
            }
            $this->info = '删除成功';

            return true;
        } else {
            $this->error = '删除失败';

            return false;
        }
    }

    public function lock()
    {
        if (empty($this->data)) {
            $this->error = trans('base.select_node');
            return false;
        }
        if (method_exists($this, '_before_lock')) {
            $before = $this->_before_lock();
            if (!is_null($before)) {
                return $before;
            }
        }
        $model = $this->getModel();
        $pk = $model->getKeyName();
        $query = $model->getQueryByModel();
        if (!empty($this->data[$pk])) {
            $query->whereIn($pk, explode(',', $this->data[$pk]));
            //unset($this->data[$pk]);
        }
        if(empty($query->getQuery()->wheres)){
            $this->error = '缺失 where 条件';
            return false;
        }
        $result = $query->update($this->data);
        if ($result) {
            if (method_exists($this, '_after_lock')) {
                $after = $this->_after_lock();
                if (!is_null($after)) {
                    return $after;
                }
            }
            $this->info = '修改成功';
            return true;
        } else {
            $this->error = '修改失败';
            return false;
        }
    }

    /** 获取详情 */
    public function show()
    {
        if (method_exists($this, '_before_show')) {
            $before = $this->_before_show();
            if (!is_null($before)) {
                return $before;
            }
        }
        if (method_exists($this, '_with')) {
            $this->_with();
        }
        if (method_exists($this, '_withCount')) {
            $this->_withCount();
        }
        if (method_exists($this, '_whereHasIn')) {
            $this->_whereHasIn();
        }
        $model = $this->getModel();
        if (method_exists($model, 'filter')) {
            $model->filter($this->data);
        }
        $data = $model->getQueryByModel()->first();
        if (!empty($data)) {
            if (method_exists($this, '_after_show')) {
                $data = $this->_after_show($data);
            }
        } else {
            $data = [];
        }

        return $data;
    }

    /** 设置参数 */
    public function setSelectField($field = [])
    {
        if (!empty($field)) {
            $this->model->getQueryByModel()->addSelect($field);
        }
        return $this;
    }
}
